import {FILTER_FILE_AND_FOLDER_LIST} from "@/util/constant";
import {
    openFolderDialogApi,
    readDirApi,
    readTextFileApi,
    renameFileOrDirApi,
    writeTextFileApi,
    deleteFileOrDirApi,
    createDirectoryApi,
    moveFileOrDirApi
} from "@/util/electronAPI";

/**
 * 打开文件夹选择对话框并处理选择结果
 *
 * @returns {Promise<Object>} 包含选择结果的对象
 *          {boolean} canceled - 用户是否取消了选择
 *          {Array<string>} filePaths - 用户选择的文件夹路径数组
 *
 * @description 该函数会调用底层API打开文件夹选择对话框，并对返回结果进行处理：
 *              1. 如果用户未取消且选择了文件夹，会对路径进行标准化处理
 *              2. 所有路径都会通过replacePath函数进行格式转换
 */
export async function openFolderDialog() {

    // 调用底层API打开文件夹选择对话框
    const result = await openFolderDialogApi()

    // 如果用户选择了文件夹，则对路径进行标准化处理
    if (!result.canceled && result.filePaths.length > 0) {
        result.filePaths = result.filePaths.map(path => replacePath(path))
    }

    // 返回处理后的结果
    return result
}

/**
 * 读取指定目录的内容并进行过滤和路径标准化处理
 * 
 * @param {string} path - 要读取的目录路径
 * @returns {Promise<Array<Object>>} 处理后的文件/文件夹对象数组
 * 
 * @description 该函数会调用底层API读取目录内容，并进行以下处理：
 *              1. 使用filterFileAndFolder过滤无效项
 *              2. 对所有项目的路径进行标准化处理
 */
export async function readDir(path) {
    const list = await readDirApi(path)
    return filterFileAndFolder(list)
        .map(item => {
            item.path = replacePath(item.path)
            return item
        })
}

/**
 * 重命名文件或文件夹
 *
 * @param {string} oldPath - 原文件或文件夹路径
 * @param {string} newName - 新的文件或文件夹名称
 * @returns {Promise<any>} 重命名操作的返回结果
 *
 * @description 该函数会调用底层API将指定路径的文件或文件夹重命名为新名称
 */
export async function renameFileOrDir(oldPath, newName){
    return await renameFileOrDirApi(oldPath, newName)
}

/**
 * 读取指定文件的文本内容
 * 
 * @param {string} filePath - 要读取的文件路径
 * @returns {Promise<string>} 文件的文本内容
 * 
 * @description 该函数会调用底层API读取指定路径的文件内容
 *              并直接返回读取到的文本内容
 */
export async function readTextFile(filePath) {
    return await readTextFileApi(filePath)
}

/**
 * 将文本内容写入指定文件
 *
 * @param {string} filePath - 要写入的文件路径
 * @param {string} content - 要写入的文本内容
 * @returns {Promise<any>} 文件写入操作的返回结果
 *
 * @description 该函数会调用底层API将指定的文本内容写入到指定路径的文件中
 */
export async function writeTextFile(filePath, content){
    return await writeTextFileApi(filePath, content)
}

/**
 * 删除指定的文件或文件夹
 *
 * @param {string} filePath - 要删除的文件或文件夹路径
 * @returns {Promise<any>} 删除操作的返回结果
 *
 * @description 该函数会调用底层API删除指定路径的文件或文件夹
 */
export async function deleteFileOrDir(filePath){
    return await deleteFileOrDirApi(filePath)
}

/**
 * 创建目录
 *
 * @param {string} dirPath - 要创建的目录路径
 * @returns {Promise<any>} 创建目录操作的返回结果
 *
 * @description 该函数会调用底层API创建指定路径的目录
 */
export async function createDirectory(dirPath){
    return await createDirectoryApi(dirPath)
}

/**
 * 移动文件或文件夹
 *
 * @param {string} sourcePath - 源文件或文件夹路径
 * @param {string} targetPath - 目标文件或文件夹路径
 * @returns {Promise<any>} 移动操作的返回结果
 *
 * @description 该函数会调用底层API将文件或文件夹从源路径移动到目标路径
 */
export async function moveFileOrDir(sourcePath, targetPath){
    return await moveFileOrDirApi(sourcePath, targetPath)
}

/**
 * 过滤文件和文件夹列表
 * @param list
 * @returns {*}
 */
export function filterFileAndFolder(list) {
    return list.filter(item => {
        return !FILTER_FILE_AND_FOLDER_LIST.includes(item.name)
    })
}

/**
 * 将path中的'\\'替换为'/'
 */
export function replacePath(path) {
    return path.replace(/\\/g, '/')
}

/**
 * 异步加载指定路径下的所有文件和文件夹信息。
 *
 * @param {string} path - 要遍历的根目录路径。
 * @returns {Promise<Array>} 包含所有文件和文件夹信息的数组，每个元素包含路径和类型（'file' 或 'directory'）。
 */
export async function loadAllFileAndFolderInfo(path) {
    const allList = []
    // 存储待处理的目录路径队列
    const waitList = [path]

    // 使用广度优先遍历方式递归读取目录内容
    while (waitList.length > 0) {
        const currentPath = waitList.shift()
        const currentList = await readDir(currentPath)
        allList.push(...currentList)
        waitList.push(...currentList.filter(item => item.type === 'directory').map(item => item.path))
    }
    return allList
}